package cn.cxyxj.code_auth_jwt_persistence_prod.auth;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


/**
 * JSON格式的用户名密码登录过滤器
 * @author cxyxj
 */
public class UsernamePasswordJsonAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private static final Logger LOGGER = LoggerFactory.getLogger(UsernamePasswordJsonAuthenticationFilter.class);

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!"POST".equals(request.getMethod())) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        String contentType = request.getContentType();
        // 如果没有指定 contentType，则抛出异常，也就是只支持解析 JSON 格式请求报文
        if(Objects.isNull(contentType)){
            throw new AuthenticationServiceException(
                    "Authentication contentType not supported: " + request.getMethod());
        }
        if (contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
            Map<String, String> loginData;
            // 获得请求参数
            try {
                loginData = new ObjectMapper().readValue(request.getInputStream(), Map.class);
            } catch (IOException e) {
                LOGGER.error("JSON转换异常");
                throw new AuthenticationServiceException("JSON转换异常");
            }
            String account = loginData.get(getUsernameParameter());
            String password = loginData.get(getPasswordParameter());
            if(StringUtils.isEmpty(account)){
                throw new AuthenticationServiceException("账号不能为空");
            }
            if(StringUtils.isEmpty(password)){
                throw new AuthenticationServiceException("密码不能为空");
            }
            // 构建 UsernamePasswordAuthenticationToken 对象
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                    account, password);
            setDetails(request, authRequest);
            //调用 authenticate 方法
            //最终会调用自定义的 UserDetailsServiceImpl 的 loadUserByUsername 方法
            return this.getAuthenticationManager().authenticate(authRequest);
        }
        return null;
    }


}

